; ReadDisk(DWORD nSectors, LPVOID lpDstBuf, DWORD dwLBA)
; 读取主磁盘上若干扇区
; @param nSectors 读取的扇区数（取值范围：0 ~ 255，其中 0 表示读取 256 个扇区）
; @param lpDstBuf 指向读取缓冲区
; @param dwLBA 读取的起始扇区（LBA 方式）
; @remark 本函数不处理异常情况，只能在 bootloader 中使用（如：加载 Kernel 到内存），需要由调用者保证传入的参数不引发异常

%ifndef BOOT_PROTECTEDMODEUTILITY_READDISK
%define BOOT_PROTECTEDMODEUTILITY_READDISK
%include "Boot/ProtectedModeUtility/ReadSector.asm"
; 最多可尝试 9 次
%define nSectors dword [ebp + 36]
%define lpDstBuf dword [ebp + 40]
%define dwLBA    dword [ebp + 44]
bits 32
Boot.ProtectedModeUtility.ReadDisk:
    pusha
    mov ebp, esp
    mov ecx, nSectors ; 待读取扇区数 
Boot.ProtectedModeUtility.ReadDisk.Loop:
    push dwLBA
    push lpDstBuf
    call Boot.ProtectedModeUtility.ReadSector ; 读取一个扇区
    add esp, 8 ; 弹出栈顶参数
    jc Boot.ProtectedModeUtility.ReadDisk.Error
    ; 更新读磁盘参数
    add lpDstBuf, 512 ; 缓冲区起始位置后移 512 字节，为一扇区大小
    inc dwLBA ; 下一个 LBA 扇区
    loop Boot.ProtectedModeUtility.ReadDisk.Loop
Boot.ProtectedModeUtility.ReadDisk.Return:
    popa
    ret
Boot.ProtectedModeUtility.ReadDisk.Error:
    stc ; 读取出现错误
    jmp Boot.ProtectedModeUtility.ReadDisk.Return
%undef nSectors
%undef lpDstBuf
%undef dwLBA
%endif